package com.educatioin.manage.wechat.service;

import com.educatioin.manage.common.beans.Response;
import com.educatioin.manage.utils.ServerUtil;
import com.educatioin.manage.web.studytours.po.ProductPo;
import com.educatioin.manage.web.studytours.po.StudyAbroadProductPo;
import com.educatioin.manage.web.studytours.po.StudyToursProductPo;
import com.educatioin.manage.web.studytours.repository.StudyAbroadProductRepository;
import com.educatioin.manage.web.studytours.repository.StudyToursProductRepository;
import com.educatioin.manage.web.system.po.CustomerPo;
import com.educatioin.manage.web.system.po.CustomerProductCollectPo;
import com.educatioin.manage.web.system.po.CustomerProductShoppingCartPo;
import com.educatioin.manage.web.system.po.LoginHistoryPo;
import com.educatioin.manage.web.system.repository.CustomerProductCollectRespository;
import com.educatioin.manage.web.system.repository.CustomerProductShoppingCartRespository;
import com.educatioin.manage.web.system.repository.CustomerRepository;
import com.educatioin.manage.web.system.repository.LoginHistoryRepository;
import com.educatioin.manage.wechat.dto.StudyProductDto;
import com.educatioin.manage.wechat.request.AddShoppingCartReq;
import com.educatioin.manage.wechat.request.CustomerLoginReq;
import com.educatioin.manage.wechat.request.CustomerSignReq;
import com.educatioin.manage.wechat.response.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by BensonZc on 2018/4/22.
 */
@Service
public class WeChatCustomerService {

    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private LoginHistoryRepository loginHistoryRepository;
    @Resource
    private CustomerProductCollectRespository customerProductCollectRespository;
    @Resource
    private CustomerProductShoppingCartRespository customerProductShoppingCartRespository;
    @Resource
    private StudyToursProductRepository studyToursProductRepository;
    @Resource
    private StudyAbroadProductRepository studyAbroadProductRepository;

    @Transactional
    public CustomerSignRsp customerSign(HttpServletRequest request, CustomerSignReq customerSignReq){
        CustomerSignRsp customerSignRsp = new CustomerSignRsp();

        if(StringUtils.isBlank(customerSignReq.getCustomerName()) || StringUtils.isBlank(customerSignReq.getCustomerPhone()) || StringUtils.isBlank(customerSignReq.getCustomerPassword())){
            customerSignRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerSignRsp.setReturnMsg("客户名、手机号或密码不能为空！");
            return customerSignRsp;
        }

        CustomerPo customerPo = customerRepository.findByPhone(customerSignReq.getCustomerPhone());
        if(null != customerPo){
            customerSignRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerSignRsp.setReturnMsg("客户已存在！");
            return customerSignRsp;
        }

        customerPo = new CustomerPo();
        customerPo.setType(1); //普通客户
        customerPo.setCode(UUID.randomUUID().toString());
        customerPo.setName(customerSignReq.getCustomerName());
        customerPo.setPhone(customerSignReq.getCustomerPhone());
        customerPo.setPassword(customerSignReq.getCustomerPassword());
        customerPo.setCreateTime(System.currentTimeMillis());
        customerPo.setCreateUser(customerSignReq.getCustomerName());
        customerPo.setEnabled(true);

        customerRepository.save(customerPo);

        //登录历史表新增记录
        String token = getCustomerCode();
        LoginHistoryPo loginHistoryPo = new LoginHistoryPo();
        loginHistoryPo.setCustomerId(customerPo.getId());
        loginHistoryPo.setCustomerName(customerSignReq.getCustomerPhone());
        loginHistoryPo.setLoginTime(System.currentTimeMillis());
        loginHistoryPo.setToken(token);
        loginHistoryRepository.save(loginHistoryPo);

        customerSignRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        customerSignRsp.setToken(token);

        //登录信息放到session中
        request.getSession().setAttribute("loginPhone", customerSignReq.getCustomerPhone());
        request.getSession().setAttribute("token", token);
        return customerSignRsp;
    }

    @Transactional
    public CustomerLoginRsp buyLogin(HttpServletRequest request, String phone){
        CustomerLoginRsp customerLoginRsp = new CustomerLoginRsp();

        if(StringUtils.isBlank(phone)){
            customerLoginRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerLoginRsp.setReturnMsg("手机号不能为空！");
            return customerLoginRsp;
        }

        CustomerPo customerPo = customerRepository.findByName(phone);
        if(null == customerPo){
            customerLoginRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerLoginRsp.setReturnMsg("客户不存在！");
            return customerLoginRsp;
        }

        //登录历史表新增记录
        String token = getCustomerCode();

        LoginHistoryPo loginHistoryPo = new LoginHistoryPo();
        loginHistoryPo.setCustomerId(customerPo.getId());
        loginHistoryPo.setCustomerName(phone);
        loginHistoryPo.setLoginTime(System.currentTimeMillis());
        loginHistoryPo.setToken(token);
        loginHistoryRepository.save(loginHistoryPo);

        customerLoginRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        customerLoginRsp.setToken(token);

        //登录信息放到session中
        request.getSession().setAttribute("loginPhone", phone);
        request.getSession().setAttribute("token", token);
        return customerLoginRsp;
    }

    @Transactional
    public CustomerLoginRsp customerLogin(HttpServletRequest request, CustomerLoginReq customerLoginReq){
        CustomerLoginRsp customerLoginRsp = new CustomerLoginRsp();

        if(StringUtils.isBlank(customerLoginReq.getCustomerName()) || StringUtils.isBlank(customerLoginReq.getCustomerPassword())){
            customerLoginRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerLoginRsp.setReturnMsg("手机号或密码不能为空！");
            return customerLoginRsp;
        }

        CustomerPo customerPo = customerRepository.findByPhone(customerLoginReq.getCustomerName());
        if(null == customerPo){
            customerLoginRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            customerLoginRsp.setReturnMsg("客户不存在！");
            return customerLoginRsp;
        }

        if(customerLoginReq.getCustomerPassword().equals(customerPo.getPassword())){
            customerLoginRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
            String token = getCustomerCode();
            customerLoginRsp.setToken(token);

            //登录历史表新增记录
            LoginHistoryPo loginHistoryPo = new LoginHistoryPo();
            loginHistoryPo.setCustomerId(customerPo.getId());
            loginHistoryPo.setCustomerName(customerLoginReq.getCustomerName());
            loginHistoryPo.setLoginTime(System.currentTimeMillis());
            loginHistoryPo.setToken(token);
            loginHistoryRepository.save(loginHistoryPo);

            //登录信息放到session中
            request.getSession().setAttribute("loginPhone", customerLoginReq.getCustomerName());
            request.getSession().setAttribute("token", token);
            return customerLoginRsp;
        }

        customerLoginRsp.setReturnCode(Response.RETURN_FAIL_CODE);
        customerLoginRsp.setReturnMsg("客户密码不正确！");
        return customerLoginRsp;
    }

    public GetCustomerInfoRsp getCustomerInfo(String token){
        GetCustomerInfoRsp getCustomerInfoRsp = new GetCustomerInfoRsp();

        CustomerPo customerPo = checkLoginToken(getCustomerInfoRsp, token);

        if(null != getCustomerInfoRsp.getReturnCode() && Response.RETURN_FAIL_CODE == getCustomerInfoRsp.getReturnCode()){
            return getCustomerInfoRsp;
        }

        getCustomerInfoRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        getCustomerInfoRsp.setCustomerName(customerPo.getName());
        getCustomerInfoRsp.setCustomerCode(customerPo.getCode());
        getCustomerInfoRsp.setCustomerType(customerPo.getType());
        getCustomerInfoRsp.setPoint(customerPo.getPoint());

        return getCustomerInfoRsp;
    }

    public Response collectProduct(HttpServletRequest request, Long productId, Integer productType){
        Response response = new Response();

        Object loginPhone = request.getSession().getAttribute("loginPhone");
        if(null == loginPhone || StringUtils.isBlank(loginPhone.toString())){
            response.setReturnCode(Response.RETURN_NO_LOGIN);
            response.setReturnMsg("请先登录！");
            return response;
        }

        if(checkStudyType(productType, productId)){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("产品不存在！");
            return response;
        }

        CustomerPo customerPo = customerRepository.findByPhone(loginPhone.toString());
        if(null == customerPo){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("客户不存在！");
            return response;
        }

        CustomerProductCollectPo customerProductCollectPo = customerProductCollectRespository.findByCustomerIdAndProductId(customerPo.getId(), productId);
        if(null == customerProductCollectPo){
            customerProductCollectPo = new CustomerProductCollectPo();
            customerProductCollectPo.setCustomerId(customerPo.getId());
            customerProductCollectPo.setProductId(productId);
            customerProductCollectPo.setCreateTime(System.currentTimeMillis());
            customerProductCollectPo.setType(productType);
            customerProductCollectRespository.save(customerProductCollectPo);
        }else{
            customerProductCollectRespository.delete(customerProductCollectPo);
        }
        response.setReturnCode(Response.RETURN_SUCCESS_CODE);
        return response;
    }

    public Response shoppingCart(HttpServletRequest request, AddShoppingCartReq addShoppingCartReq) throws IOException {
        Response response = new Response();

        Object loginPhone = request.getSession().getAttribute("loginPhone");
        if(null == loginPhone || StringUtils.isBlank(loginPhone.toString())){
            response.setReturnCode(Response.RETURN_NO_LOGIN);
            response.setReturnMsg("请先登录！");
            return response;
        }

        Long productId = addShoppingCartReq.getProductId();

        if(checkStudyType(addShoppingCartReq.getProductType(), productId)){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("产品不存在！");
            return response;
        }

        CustomerPo customerPo = customerRepository.findByPhone(loginPhone.toString());
        if(null == customerPo){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("客户不存在！");
            return response;
        }

        CustomerProductShoppingCartPo customerProductShoppingCartPo = customerProductShoppingCartRespository.findByCustomerIdAndProductId(customerPo.getId(), productId);
        if(null == customerProductShoppingCartPo){
            customerProductShoppingCartPo = new CustomerProductShoppingCartPo();
            customerProductShoppingCartPo.setCustomerId(customerPo.getId());
            customerProductShoppingCartPo.setProductId(productId);
            customerProductShoppingCartPo.setCreateTime(System.currentTimeMillis());

            customerProductShoppingCartPo.setProductImage(addShoppingCartReq.getProductImage());
            customerProductShoppingCartPo.setProductName(addShoppingCartReq.getProductName());
            customerProductShoppingCartPo.setProductCode(addShoppingCartReq.getProductCode());
            customerProductShoppingCartPo.setProductDeposit(addShoppingCartReq.getProductDeposit());
            customerProductShoppingCartPo.setApplicantName(addShoppingCartReq.getApplicantName());
            customerProductShoppingCartPo.setGroupName(addShoppingCartReq.getGroupName());
            customerProductShoppingCartPo.setPhone(addShoppingCartReq.getPhone());
            customerProductShoppingCartPo.setProductType(addShoppingCartReq.getProductType());

            customerProductShoppingCartPo.setSchool(addShoppingCartReq.getSchoolGradeClazz().split(",")[0]);
            customerProductShoppingCartPo.setGrade(addShoppingCartReq.getSchoolGradeClazz().split(",")[1]);
            customerProductShoppingCartPo.setClazz(addShoppingCartReq.getSchoolGradeClazz().split(",")[2]);
            customerProductShoppingCartPo.setRecommenderCode(addShoppingCartReq.getRecommenderCode());

            customerProductShoppingCartPo.setOpenid(addShoppingCartReq.getOpenid());
            String requestIp = ServerUtil.getIpAddress(request);
            customerProductShoppingCartPo.setRequestIp(requestIp);
            customerProductShoppingCartRespository.save(customerProductShoppingCartPo);
        }else{
            customerProductShoppingCartRespository.delete(customerProductShoppingCartPo);
        }

        response.setReturnCode(Response.RETURN_SUCCESS_CODE);
        return response;
    }

    public MyCollectionRsp myCollection(HttpServletRequest request){
        MyCollectionRsp myCollectionRsp = new MyCollectionRsp();

        Object loginPhone = request.getSession().getAttribute("loginPhone");
        if(null == loginPhone || StringUtils.isBlank(loginPhone.toString())){
            myCollectionRsp.setReturnCode(Response.RETURN_NO_LOGIN);
            myCollectionRsp.setReturnMsg("请先登录！");
            return myCollectionRsp;
        }

        CustomerPo customerPo = customerRepository.findByPhone(loginPhone.toString());
        if(null == customerPo){
            myCollectionRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            myCollectionRsp.setReturnMsg("客户不存在！");
            return myCollectionRsp;
        }
        List<ProductPo> collections = new ArrayList<>();
        List<StudyProductDto> studyProductDtos = Lists.newArrayList();
        List<CustomerProductCollectPo> myCollections = customerProductCollectRespository.findByCustomerId(customerPo.getId());
        if(CollectionUtils.isNotEmpty(myCollections)){
            List<Long> productIds = Lists.newArrayList();
            List<Integer> productTypes = Lists.newArrayList();
            for(CustomerProductCollectPo customerProductCollectPo : myCollections){
                productIds.add(customerProductCollectPo.getProductId());
                productTypes.add(customerProductCollectPo.getType());
            }

            for(int i=0;i<productIds.size();i++){
                if(productTypes.get(i)==0){
                    StudyToursProductPo studyToursProductPo = studyToursProductRepository.findOne(productIds.get(i));
                    if(null!=studyToursProductPo) {
                        collections.add(studyToursProductPo);
                    }
                }else if(productTypes.get(i)==1){
                    StudyAbroadProductPo studyAbroadProductPo = studyAbroadProductRepository.findOne(productIds.get(i));
                    if(null!=studyAbroadProductPo) {
                        collections.add(studyAbroadProductPo);
                    }
                }
            }

//            List<StudyToursProductPo> collections = studyToursProductRepository.findAll((root, query, cb) -> {
//                List<Predicate> predicates = Lists.newArrayList();
//                if(CollectionUtils.isNotEmpty(productIds)) {
//                    CriteriaBuilder.In<Long> in = cb.in(root.get("id").as(Long.class));
//                    for (Long productId : productIds) {
//                        in.value(productId);
//                    }
//                    predicates.add(in);
//                }
//                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
//            });
            if(CollectionUtils.isNotEmpty(collections)){
                for(ProductPo productPo : collections){
                    StudyProductDto studyProductDto = new StudyProductDto();
                    if(productPo instanceof StudyToursProductPo){
                        studyProductDto.setId(((StudyToursProductPo)productPo).getId());
                        studyProductDto.setProductName(((StudyToursProductPo)productPo).getName());
                        studyProductDto.setShowImage(((StudyToursProductPo)productPo).getShowImage());
                        studyProductDto.setPrice(((StudyToursProductPo)productPo).getPrice());
                        studyProductDto.setDeposit(((StudyToursProductPo)productPo).getDeposit());
                        studyProductDto.setDescription(((StudyToursProductPo)productPo).getDescription());
                        studyProductDto.setProductType(0);
                        studyProductDtos.add(studyProductDto);
                    }else if (productPo instanceof StudyAbroadProductPo){
                        studyProductDto.setId(((StudyAbroadProductPo)productPo).getId());
                        studyProductDto.setProductName(((StudyAbroadProductPo)productPo).getName());
                        studyProductDto.setShowImage(((StudyAbroadProductPo)productPo).getShowImage());
                        studyProductDto.setPrice(((StudyAbroadProductPo)productPo).getPrice());
                        studyProductDto.setDeposit(((StudyAbroadProductPo)productPo).getDeposit());
                        studyProductDto.setDescription(((StudyAbroadProductPo)productPo).getDescription());
                        studyProductDto.setProductType(1);
                        studyProductDtos.add(studyProductDto);
                    }
                }


            }
        }
        myCollectionRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        myCollectionRsp.setStpCollections(studyProductDtos);
        return myCollectionRsp;
    }

    public MyShoppingCartRsp myShoppingCarts(HttpServletRequest request){
        MyShoppingCartRsp myShoppingCartRsp = new MyShoppingCartRsp();

        Object loginPhone = request.getSession().getAttribute("loginPhone");
        if(null == loginPhone || StringUtils.isBlank(loginPhone.toString())){
            myShoppingCartRsp.setReturnCode(Response.RETURN_NO_LOGIN);
            myShoppingCartRsp.setReturnMsg("请先登录！");
            return myShoppingCartRsp;
        }

        CustomerPo customerPo = customerRepository.findByPhone(loginPhone.toString());
        if(null == customerPo){
            myShoppingCartRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            myShoppingCartRsp.setReturnMsg("客户不存在！");
            return myShoppingCartRsp;
        }

        List<CustomerProductShoppingCartPo> myShoppingCarts = customerProductShoppingCartRespository.findByCustomerId(customerPo.getId());
        List<ProductPo> collections = new ArrayList<>();
        List<StudyProductDto> studyProductDtos = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(myShoppingCarts)){
            List<Long> productIds = Lists.newArrayList();
            List<Integer> productTypes = Lists.newArrayList();
            for(CustomerProductShoppingCartPo customerProductShoppingCartPo : myShoppingCarts){
                productIds.add(customerProductShoppingCartPo.getProductId());
                productTypes.add(customerProductShoppingCartPo.getProductType());
            }

            for(int i=0;i<productIds.size();i++){
                if(productTypes.get(i)==0){
                    StudyToursProductPo studyToursProductPo = studyToursProductRepository.findOne(productIds.get(i));
                    if(null!=studyToursProductPo) {
                        collections.add(studyToursProductPo);
                    }
                }else if(productTypes.get(i)==1){
                    StudyAbroadProductPo studyAbroadProductPo = studyAbroadProductRepository.findOne(productIds.get(i));
                    if(null!=studyAbroadProductPo) {
                        collections.add(studyAbroadProductPo);
                    }
                }
            }
//            List<StudyToursProductPo> collections = studyToursProductRepository.findAll((root, query, cb) -> {
//                List<Predicate> predicates = Lists.newArrayList();
//                if(CollectionUtils.isNotEmpty(productIds)) {
//                    CriteriaBuilder.In<Long> in = cb.in(root.get("id").as(Long.class));
//                    for (Long productId : productIds) {
//                        in.value(productId);
//                    }
//                    predicates.add(in);
//                }
//                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
//            });

            if(CollectionUtils.isNotEmpty(collections)){

                for(ProductPo productPo : collections){
                    StudyProductDto studyProductDto = new StudyProductDto();
                    if(productPo instanceof StudyToursProductPo){
                        studyProductDto.setId(((StudyToursProductPo)productPo).getId());
                        studyProductDto.setProductName(((StudyToursProductPo)productPo).getName());
                        studyProductDto.setShowImage(((StudyToursProductPo)productPo).getShowImage());
                        studyProductDto.setPrice(((StudyToursProductPo)productPo).getPrice());
                        studyProductDto.setDeposit(((StudyToursProductPo)productPo).getDeposit());
                        studyProductDto.setDescription(((StudyToursProductPo)productPo).getDescription());
                        studyProductDto.setProductType(0);
                        studyProductDtos.add(studyProductDto);
                    }else if (productPo instanceof StudyAbroadProductPo){
                        studyProductDto.setId(((StudyAbroadProductPo)productPo).getId());
                        studyProductDto.setProductName(((StudyAbroadProductPo)productPo).getName());
                        studyProductDto.setShowImage(((StudyAbroadProductPo)productPo).getShowImage());
                        studyProductDto.setPrice(((StudyAbroadProductPo)productPo).getPrice());
                        studyProductDto.setDeposit(((StudyAbroadProductPo)productPo).getDeposit());
                        studyProductDto.setDescription(((StudyAbroadProductPo)productPo).getDescription());
                        studyProductDto.setProductType(1);
                        studyProductDtos.add(studyProductDto);
                    }
                }

            }

        }
        myShoppingCartRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        myShoppingCartRsp.setStpCollections(studyProductDtos);
        myShoppingCartRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        myShoppingCartRsp.setStpShoppingCarts(myShoppingCarts);
        return myShoppingCartRsp;
    }

    private CustomerPo checkLoginToken(Response response, String token){
        if(StringUtils.isBlank(token)){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("登录token不能为空！");
        }

        LoginHistoryPo loginHistoryPo = loginHistoryRepository.findByToken(token);
        if(null == loginHistoryPo){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("当前用户未登录！");
        }

        CustomerPo customerPo = customerRepository.findOne(loginHistoryPo.getCustomerId());
        if(null == customerPo){
            response.setReturnCode(Response.RETURN_FAIL_CODE);
            response.setReturnMsg("用户不存在！");
        }

        return customerPo;
    }

    private String getCustomerCode() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String newDate = sdf.format(new Date());
        String result = "";
        Random random = new Random();
        for(int i = 0; i < 5; i++){
            result += random.nextInt(10);
        }
        return newDate + result;
    }

    private boolean checkStudyType(Integer type, Long productId){
        if(type == 0){
            StudyToursProductPo studyToursProductPo = studyToursProductRepository.findOne(productId);
            if(null == studyToursProductPo){
                return true;
            }
        }else if(type == 1){
            StudyAbroadProductPo studyAbroadProductPo = studyAbroadProductRepository.findOne(productId);
            if(null == studyAbroadProductPo){
                return true;
            }
        }
        return false;
    }
}
